home *** CD-ROM | disk | FTP | other *** search
- /*----------------------------------------------------------------------------
-
- Module name: TopDraw
-
- Author: Toby Howard
-
- Function: Implements the PHIGS structure network topology drawing tool.
-
- External function list: ptk_topology.
-
- Internal function list:
-
- Hashtables used: "structureid", "name", "label".
-
- Modification history: (Version), (Date), (Name), (Description).
-
- 1.0, ????, Toby Howard, First version.
-
- 1.1, 29th July 1988, Steve Larkin, Modified to use Vax Phigs instead of
- KRT3.
-
- 2.0, 10th June 1991, Gareth Williams, Translated to C.
-
- 3.0, June 1992, Gareth Williams, Converted to ISO PHIGS C.
-
- ----------------------------------------------------------------------------*/
-
- #include <stdio.h>
- #include <math.h>
- #include <phigs.h>
- #include "ptk.h"
-
- /*--------------------------------------------------------------------------*/
-
- /* The width and height of the nodes in the diagram */
-
- #define WIDTH 1.0
-
- #define HEIGHT 1.0
-
- /* The horizontal and vertical separations of the nodes */
-
- #define HSPACING (3.0 * WIDTH)
-
- #define VSPACING (4.0 * HEIGHT)
-
- /* for storage of structure information */
-
- typedef struct ptksstruct
- {
- Pint name; /* structure identifier */
- Pint numchildren; /* number of children */
- Pint numunique; /* number of unique children */
- Pint level; /* max level in picture */
- Ppoint pos; /* position in picture */
- ptkboolean placed; /* placed yet? */
- struct ptksref *firstchild, *lastchild; /* list of children */
- struct ptksref *firstparent, *lastparent; /* list of parents */
- struct ptksstruct *next; /* next ptksstruct record */
- } ptksstruct;
-
- /* for storage of structure references */
-
- typedef struct ptksref
- {
- ptksstruct *structptr; /* structure being referenced */
- Pint element; /* element doing the referencing */
- struct ptksref *next; /* next ptksreference */
- } ptksref;
-
- /* this is a node in the diagram */
-
- typedef struct ptksnode
- {
- ptksstruct *structptr;
- struct ptksnode *next;
- } ptksnode;
-
- /* this is for the list of rows */
-
- typedef struct ptksrow
- {
- Pint num;
- ptksnode *n;
- struct ptksrow *next;
- } ptksrow;
-
- typedef struct ptkskeytable
- {
- char key[256], an[256];
- } ptkskeytable;
-
- typedef struct ptkstopdraw
- {
- Pint topologyid;
- Pint topologystid;
- ptketopologytype topologytype;
- Pint txfont;
- Pint textcolour;
- Pint linecolour;
- Pint edgecolour;
- Pint intcolour;
- Pint topologyname;
- Pint_list posted;
-
- /* highlight node */
- Pint highlightnode;
- Pint highlightedge;
- Pint highlightint;
-
- struct ptkstopdraw *next;
-
- Pint root;
-
- Pint_list hlist; /* list of nodes to highlight ? */
- ptksstruct *structlist; /* the head of the structure info list */
- ptksrow *rowlist; /* the head of the row list */
-
- Pmatrix3 globaltran, mat;
- Pelem_ref_list_list *pathlist; /* structure network paths */
- Pstore pathdata; /* buffer to hold paths data */
-
- Pfloat annotextheight; /* size of characters for annotation */
- Pint nodebounds; /* for drawing the nodes */
- Ppoint nodepoints[5];
- Pfloat nodeheight, nodewidth;
-
- Plimit3 extent;
- Pfloat xinc, yinc;
- Pfloat rowmaxx[255];
- Pfloat topx, topy;
- Pint maxlevel;
-
- ptkskeytable keytablelst[255];
- Pint keyno;
- } ptkstopdraw;
-
- /*--------------------------------------------------------------------------*/
-
- static ptkstopdraw *topptr = NULL;
-
- static ptkstopdraw *firsttop = NULL;
- static ptkstopdraw *lasttop = NULL;
- static nodeidcount = 0;
-
- static topologycount = 0;
-
- /*--------------------------------------------------------------------------*/
-
- static void settop(C(Pint) topid)
- PreANSI(Pint topid)
- {
- ptkstopdraw *ptr;
-
- if (firsttop == NULL)
- {
- topptr = NULL;
- return;
- }
- ptr = firsttop;
- while (ptr->topologyid != topid)
- {
- ptr = ptr->next;
- if (ptr == NULL)
- {
- topptr = NULL;
- return;
- }
- }
- topptr = ptr;
- } /* settop */
-
- /*--------------------------------------------------------------------------*/
-
- static void note(C(Pfloat) xx, C(Pfloat) yy)
- PreANSI(Pfloat xx)
- PreANSI(Pfloat yy)
- /*
- ** \parambegin
- ** \param{}{xx}{x coordinate}{IN}
- ** \param{}{yy}{y coordinate}{IN}
- ** \paramend
- ** \blurb{Updates `extent' using xx, yy.}
- */
- {
- if (xx > topptr->extent.x_max)
- topptr->extent.x_max = xx;
- if (yy > topptr->extent.y_max)
- topptr->extent.y_max = yy;
- if (xx < topptr->extent.x_min)
- topptr->extent.x_min = xx;
- if (yy < topptr->extent.y_min)
- topptr->extent.y_min = yy;
- } /* note */
-
- /*--------------------------------------------------------------------------*/
-
- /* Key handling
- **
- ** When the algorithm has drawn the nodes for all the structures in
- ** the hierarchy, it attempts to draw the structure names against the nodes,
- ** and tries various positions to avoid overlapping with adjacent nodes. If
- ** it is unable to place the text reasonably, it gives up, and resorts to
- ** a simple 'key' scheme, where the name is associated with a key, and the
- ** node is labelled with the key instead of the full name (the assumption
- ** being that the key will be only a few characters long. If keys are used, a
- ** list of keys and their corresponding names is added to the picture at the
- ** end.
- */
-
- /*--------------------------------------------------------------------------*/
-
- static void setkey(C(char *) v, C(char *) k)
- PreANSI(char *v)
- PreANSI(char *k)
- /*
- ** \parambegin
- ** \param{}{v}{string to allocate a key for}{IN}
- ** \param{}{k}{key allocated to string ( a, b etc.)}{IN}
- ** \paramend
- ** \blurb{Allocates a key to string 'v', and records the correspondence
- ** in the key table.}
- */
- {
- ptkskeytable *keyptr;
-
- topptr->keyno++;
- keyptr = &topptr->keytablelst[topptr->keyno - 1];
- keyptr->key[1] = '\0';
- keyptr->key[0] = (char)(topptr->keyno + 96);
-
- /* keys are labelled from 'a' upwards */
- strcpy(k, keyptr->key); /* return the key allocated */
- strcpy(keyptr->an, v);
- } /* setkey */
-
- /*--------------------------------------------------------------------------*/
-
- static void drawkeys(C(void))
- /*
- ** \blurb{Start the list of keys at xmin, and drop a node's
- ** worth below the minimum y.}
- */
- {
- Pint i;
- Ppoint tp;
- ptkskeytable *keyptr;
- char str[256];
-
- if (topptr->keyno > 0)
- {
- tp = ptk_point(topptr->extent.x_min,
- topptr->extent.y_min - topptr->nodeheight);
- for (i = 0; i < topptr->keyno; i++)
- {
- keyptr = &topptr->keytablelst[i];
- sprintf(str, "%s %s", keyptr->key, keyptr->an);
- tp.y -= topptr->annotextheight * 1.5;
- ptext(&tp, str);
- }
- /* Record the limits of the keytable */
- note(tp.x, tp.y);
- }
- } /* drawkeys */
-
- /*--------------------------------------------------------------------------*/
-
- static void setscaling(C(void))
- /*
- ** \blurb{Computes the transformation to scale the picture
- ** into [0,1], and inserts a setglobaltran at the start of the picture.}
- */
- {
- Ppoint3 sc, sh;
- Pint err, el;
- Pfloat height, width, scale;
- Ppoint3 topshift, topscale;
-
- topptr->extent.x_min -= topptr->nodewidth;
- topptr->extent.x_max += topptr->nodewidth;
- topptr->extent.y_min -= topptr->nodeheight;
- topptr->extent.y_max += topptr->nodeheight;
- height = topptr->extent.y_max - topptr->extent.y_min;
- width = topptr->extent.x_max - topptr->extent.x_min;
- scale = 1.0/PTKMAX(height, width);
- topshift = ptk_point3(-topptr->extent.x_min - (width / 2.0),
- -topptr->extent.y_min - (height / 2.0), 0.0),
- ptk_shift3(&topshift, PTYPE_REPLACE, topptr->globaltran);
- topscale = ptk_point3(scale, scale, scale);
- ptk_scale3(&topscale, PTYPE_POSTCONCAT, topptr->globaltran);
- topshift = ptk_point3(0.5, 0.5, 0.0);
- ptk_shift3(&topshift, PTYPE_POSTCONCAT, topptr->globaltran);
- /* Squeeze in a global transformation at the
- top of the structure */
- pset_elem_ptr(0);
- pset_elem_ptr_label(ptk_stringtoint("label", "globaltran"));
- pset_global_tran3(topptr->globaltran);
- } /* setscaling */
-
- /*--------------------------------------------------------------------------*/
-
- static ptkboolean overlap(C(Ppoint *) p, C(Pfloat) stringw, C(Pfloat) stringh)
- PreANSI(Ppoint *p)
- PreANSI(Pfloat stringw)
- PreANSI(Pfloat stringh)
- /*
- ** \parambegin
- ** \param{}{p}{point to check for overlapping nodes}{IN}
- ** \param{}{stringw}{character string width}{IN}
- ** \param{}{stringh}{character string height}{IN}
- ** \paramend
- ** \blurb{Given a point p, checks against all the positioned nodes
- ** to see if any lie between p and and another point q, 'stringw'
- ** horizontally away from p.
- ** Returns TRUE if there is an overlapping node, otherwise FALSE.}
- */
- {
- ptksstruct *sp;
- ptkboolean over;
-
- over = FALSE;
- sp = topptr->structlist;
- while (sp != NULL && !over)
- {
- /* look at each node */
- if ((p->y <= sp->pos.y + topptr->nodeheight / 2.0) &&
- (p->y + stringh >= sp->pos.y - topptr->nodeheight / 2.0))
- {
- /* it overlaps the node vertically, so now test if the
- node lies somewhere inside the extent */
- if ((p->x < sp->pos.x + topptr->nodewidth / 2.0) &&
- (p->x + stringw > sp->pos.x - topptr->nodewidth / 2.0))
- over = TRUE;
- }
- sp = sp->next;
- }
- return over;
- } /* overlap */
-
- /*--------------------------------------------------------------------------*/
-
- static void setnode(C(Pfloat) w, C(Pfloat) h)
- PreANSI(Pfloat w)
- PreANSI(Pfloat h)
- /*
- ** \parambegin
- ** \param{}{w}{node width}{IN}
- ** \param{}{h}{node height}{IN}
- ** \paramend
- ** \blurb{Establishes the size of a node, centred.}
- */
- {
- topptr->nodebounds = 5;
- topptr->nodepoints[0] = ptk_point(w/-2.0, h/-2.0);
- topptr->nodepoints[1] = ptk_point(w/2.0, h/-2.0);
- topptr->nodepoints[2] = ptk_point(w/2.0, h/2.0);
- topptr->nodepoints[3] = ptk_point(w/-2.0, h/2.0);
- topptr->nodepoints[4] = ptk_point(w/-2.0, h/-2.0);
- pset_char_ht(h/2.0);
- topptr->annotextheight = h / 2.0;
- } /* setnode */
-
- /*--------------------------------------------------------------------------*/
-
- static void initialise(C(void))
- /*
- ** \blurb{Initialise topdraw values.}
- */
- {
- Pint k;
-
- topptr->structlist = NULL; /* no structures to start with */
- topptr->rowlist = NULL; /* and no rows */
- topptr->keyno = 0; /* no debugging printing, no keys */
- for (k = 0; k <= 254; k++)
- topptr->rowmaxx[k] = -32768.0;
- topptr->maxlevel = 1;
- } /* initialise */
-
- /*--------------------------------------------------------------------------*/
-
- static ptkboolean lookupstructure(C(Pint) sn, C(ptkboolean) create,
- C(ptksstruct **) sp)
- PreANSI(Pint sn)
- PreANSI(ptkboolean create)
- PreANSI(ptksstruct **sp)
- /*
- ** \parambegin
- ** \param{}{sn}{structure identifier to look up}{IN}
- ** \param{}{create}{add to structlist if TRUE, do nothing if FALSE}{IN}
- ** \param{}{sp}{pointer to structure record}{IN}
- ** \paramend
- ** \blurb{Looks for a structure in the namelist, and inserts it
- ** if it's not there, and create=TRUE. Returns a pointer to the name
- ** record, or NIL if it wasn't found and not created. The result is
- ** TRUE if it was created.
- ** Returns TRUE if new record created, otherwise FALSE.}
- */
- {
- ptkboolean found;
- ptksstruct *last, *s, *news;
-
- s = topptr->structlist;
- found = FALSE;
- *sp = NULL;
- while (!found && s != NULL)
- {
- found = (sn == s->name);
- if (found)
- break;
- last = s;
- s = s->next;
- }
- if (found)
- {
- *sp = s;
- return (!found && create);
- }
- if (!create)
- {
- return (!found && create);
- } /* not found and created */
- news = (ptksstruct *)malloc(sizeof(ptksstruct));
- *sp = news;
- if (topptr->structlist == NULL) /* initialise the record */
- topptr->structlist = news;
- else
- last->next = news;
- news->name = sn;
- news->level = 0;
- news->next = NULL;
- news->numchildren = ptk_countchildren(sn);
- news->numunique = ptk_countuniqchildren(sn);
- news->firstchild = NULL;
- news->lastchild = NULL;
- news->firstparent = NULL;
- news->lastparent = NULL;
- news->placed = FALSE;
- news->pos = ptk_point(0.0, 0.0);
- return (!found && create);
- } /* lookupstructure */
-
- /*--------------------------------------------------------------------------*/
-
- static void drawnames(C(void))
- /*
- ** \blurb{Draws the name of the structure next to its node.
- ** First we'll try and draw the string to the right of the node, which
- ** seems like a good place. If that would splash over another node
- ** nearby,we'll try the left instead. If both are no good, give up,and
- ** use a key instead.}
- */
- {
- Ppoint tp;
- ptksstruct *sp;
- Pmatrix3 mat;
- Pint textrep;
- char k[256], annot[256];
- Ptext_align a;
- Pint lenstr;
- ptkboolean donames;
-
- ptk_unitmatrix3(mat);
- pset_local_tran3(mat, PTYPE_REPLACE);
- a.hor = PHOR_NORM;
- a.vert = PVERT_HALF;
- pset_text_align(&a);
- donames = ptk_hashtableused("structureid");
- sp = topptr->structlist; /* going to scan the structure list */
- while (sp != NULL)
- {
- /* place text to the right of the node */
- tp = ptk_point(sp->pos.x + 3.0 * WIDTH / 4.0, sp->pos.y);
- if (donames)
- {
- ptk_inttostring("structureid", sp->name, 256, annot, &lenstr);
- if (lenstr == 0)
- sprintf(annot, "%d\0", sp->name);
- }
- else
- sprintf(annot, "%d\0", sp->name);
- /* should use inqtextextent to get width of string */
- if (overlap(&tp, (Pfloat)strlen(annot) * topptr->annotextheight,
- topptr->annotextheight))
- {
- /* no good. now try to place it to the left of the node */
- tp.x = sp->pos.x - topptr->nodewidth / 2.0 -
- (Pfloat)strlen(annot) * topptr->annotextheight;
- if (overlap(&tp, strlen(annot) * topptr->annotextheight,
- topptr->annotextheight))
- {
- /* Need to resort to a key here. Reset the text position
- to inside the node, and get a key */
- tp = ptk_point(sp->pos.x + 3.0 * WIDTH / 4.0, sp->pos.y);
- setkey(annot, k);
- note(tp.x + topptr->annotextheight, tp.y);
- ptext(&tp, k);
- }
- else
- {
- /* place text to the left */
- note(tp.x, tp.y);
- tp.x = sp->pos.x - topptr->nodeheight * 3.0 / 4.0;
- a.hor = PHOR_RIGHT;
- a.vert = PVERT_HALF;
- pset_text_align(&a);
- ptext(&tp, annot);
- a.hor = PHOR_NORM;
- a.vert = PVERT_HALF;
- pset_text_align(&a);
- }
- }
- else
- {
- /* no overlap */
- note(tp.x + (Pfloat)strlen(annot) * topptr->annotextheight, tp.y);
- ptext(&tp, annot);
- }
- sp = sp->next;
- }
- } /* drawnames */
-
- /*--------------------------------------------------------------------------*/
-
- static Pint findlowestchild(C(ptksstruct *) root)
- PreANSI(ptksstruct *root)
- /*
- ** \parambegin
- ** \param{}{root}{pointer to root structure record}{IN}
- ** \paramend
- ** \blurb{Looks at all the immediate children of 'root', and
- ** returns the level of the deepest one.
- ** Returns level of lowest child of root.}
- */
- {
- ptksref *r;
- Pint l;
-
- l = 0;
- r = root->firstchild;
- while (r != NULL)
- {
- if (r->structptr->level > l)
- l = r->structptr->level;
- r = r->next;
- }
- return l;
- } /* findlowestchild */
-
- /*--------------------------------------------------------------------------*/
-
- static void placetree(C(ptksstruct *) root, C(Pfloat *) x, C(Pfloat) y)
- PreANSI(ptksstruct *root)
- PreANSI(Pfloat *x)
- PreANSI(Pfloat y)
- /*
- ** \parambegin
- ** \param{}{root}{pointer to root structure record.}{IN}
- ** \param{}{x}{x coordinate of node}{IN}
- ** \param{}{y}{y coordinate of node}{IN}
- ** \paramend
- ** \blurb{Places a subtree.}
- */
- {
- Pint n, fudge;
- ptksref *r;
- Pfloat fuzz, finetune, xx, xxinc;
-
- if (root->placed)
- return;
-
- n = root->numunique;
-
- fudge = findlowestchild(root) - root->level;
-
- finetune = 1.0;
- xxinc = topptr->xinc * fudge * finetune;
-
- xx = *x - ((Pfloat)n - 1.0) * xxinc / 2.0;
- fuzz = topptr->nodewidth * 1.5;
-
- if (n > 1)
- {
- /* at least one child */
- if (xx <= topptr->rowmaxx[root->level] + fuzz)
- {
- /* printf("adjusting for overlap at level %ld\n", root->level + 1); */
- /* compute x pos of leftmost child */
- xx = topptr->rowmaxx[root->level] + xxinc;
- /* now readjust x to center node over its children */
- *x = xx + ((Pfloat)n - 1.0) * xxinc / 2.0;
- }
- }
-
- y = 0.0 - root->level * topptr->yinc;
-
- root->pos = ptk_point(*x, y);
-
- topptr->rowmaxx[root->level - 1] = *x;
-
- root->placed = TRUE;
-
- r = root->firstchild;
- while (r != NULL)
- {
- placetree(r->structptr, &xx, y);
- r = r->next;
- xx += xxinc;
- }
- } /* placetree */
-
- /*--------------------------------------------------------------------------*/
-
- static void placenodes(C(void))
- /*
- ** \blurb{Draws all the nodes for the structures in the hierarchy.}
- */
- {
- topptr->topx = 0.0;
- topptr->topy = 0.0;
- topptr->nodeheight = 1.0;
- topptr->nodewidth = 1.0;
- setnode(1.0, 1.0);
- topptr->xinc = topptr->nodewidth * 2.0;
- topptr->yinc = topptr->nodeheight * 2.0;
-
- /* start it off with a silly value */
-
- topptr->extent = ptk_limit3(1000000.0, -10000000.0, 10000000.0,
- -10000000.0, 0.0, 1.0);
-
- /* Recursively place all the nodes, starting at 0,0. The diagram
- ** will grow downwards, and its ultimate extent will be in `extent'.
- ** Everytime a new bit is drawn, its position is noted with `note',
- ** which updates the extent.
- */
-
- placetree(topptr->structlist, &topptr->topx, topptr->topy);
- } /* placenodes */
-
- /*--------------------------------------------------------------------------*/
-
- static void drawnode(C(ptksstruct *) sp)
- PreANSI(ptksstruct *sp)
- /*
- ** \parambegin
- ** \param{}{sp}{pointer to structure record}{IN}
- ** \paramend
- ** \blurb{Draws a node to represent the structure at sp in the
- ** structure list, and the node will go into the diagram at xx, yy.}
- */
- {
- Ppoint3 sh;
- Ppoint_list sets;
- Pint err, elptr;
-
- sh = ptk_point3(sp->pos.x, sp->pos.y, 0.0);
- ptk_shift3(&sh, PTYPE_REPLACE, topptr->mat);
- sets.num_points = topptr->nodebounds;
- sets.points = topptr->nodepoints;
- if (nodeidcount == topptr->highlightnode)
- {
- /* jump to `highlightnode' label */
- pinq_elem_ptr(&err, &elptr);
- pset_elem_ptr(0);
- pset_elem_ptr_label(ptk_stringtoint("label", "highlightnode"));
- pset_pick_id(sp->name);
- pset_local_tran3(topptr->mat, PTYPE_REPLACE);
- ptk_fillareaset(1, &sets);
- /* jump back */
- pset_elem_ptr(elptr + 3);
- }
- else
- {
- pset_pick_id(sp->name);
- pset_local_tran3(topptr->mat, PTYPE_REPLACE);
- ptk_fillareaset(1, &sets);
- }
- note(sp->pos.x, sp->pos.y);
- } /* drawnode */
-
- /*--------------------------------------------------------------------------*/
-
- static void drawnodes(C(void))
- /*
- ** \blurb{Draw all nodes in structure network.}
- */
- {
- ptksstruct *s;
-
- s = topptr->structlist;
- nodeidcount = 0;
- while (s != NULL)
- {
- drawnode(s);
- nodeidcount++;
- s = s->next;
- }
- } /* drawnodes */
-
- /*--------------------------------------------------------------------------*/
-
- static void drawstructnetnode(C(ptksstruct *) sp)
- PreANSI(ptksstruct *sp)
- /*
- ** \parambegin
- ** \param{}{sp}{pointer to structure record}{IN}
- ** \paramend
- ** \blurb{Draws a node to represent the structure at sp in the
- ** structure list, and the node will go into the diagram at xx, yy.}
- */
- {
- Plimit3 boundbox, nodebox;
- Pmatrix3 matrix;
- Pint err, elptr;
- Ppoint3 sh;
-
- if (ptk_boundingbox(sp->name, &boundbox, TRUE))
- {
- nodebox = ptk_limit3(-0.5, 0.5, -0.5, 0.5, 0.0, 1.0);
- sh = ptk_point3(sp->pos.x, sp->pos.y, 0.0);
- ptk_shift3(&sh, PTYPE_REPLACE, topptr->mat);
- ptk_box3tobox3(&boundbox, &nodebox, TRUE, PTYPE_PRECONCAT, topptr->mat,
- &err);
- /* jump to `globaltran' label, this avoids attribute inheritance
- ** from the topology structure.
- */
- pinq_elem_ptr(&err, &elptr);
- pset_elem_ptr(0);
- pset_elem_ptr_label(ptk_stringtoint("label", "globaltran"));
- pset_pick_id(sp->name);
- pset_local_tran3(topptr->mat, PTYPE_REPLACE);
- pexec_struct(sp->name);
- /* jump back */
- pset_elem_ptr(elptr + 3);
- note(sp->pos.x, sp->pos.y);
- }
- else
- drawnode(sp);
- } /* drawstructnetnode */
-
- /*--------------------------------------------------------------------------*/
-
- static delstructnodes()
- {
- char sname[80];
- ptksstruct *s;
-
- s = topptr->structlist;
- while (s != NULL)
- {
- if (s->numchildren > 0)
- {
- sprintf(sname, "ptk$topologynode%d", s->name);
- pdel_struct(ptk_stringtoint("structureid", sname));
- ptk_delstring("structureid", sname);
- }
- s = s->next;
- }
- } /* delstructnodes */
-
- /*--------------------------------------------------------------------------*/
-
- static void drawstructnode(C(ptksstruct *) sp)
- PreANSI(ptksstruct *sp)
- /*
- ** \parambegin
- ** \param{}{sp}{pointer to structure record}{IN}
- ** \paramend
- ** \blurb{Draws a node to represent the structure at sp in the
- ** structure list, and the node will go into the diagram at xx, yy.}
- */
- {
- Plimit3 boundbox, nodebox;
- Pmatrix3 matrix;
- Pint err, numchild, elptr, stendptr[2], lstnum;
- Ppoint3 sh;
- char sname[255];
- Pelem_type elemlist[1];
- Psearch_status srchstat;
- ptkboolean validbox;
-
- validbox = ptk_boundingbox(sp->name, &boundbox, FALSE);
- if (validbox)
- {
- if (sp->numchildren > 0)
- {
- sprintf(sname, "ptk$topologynode%d", sp->name);
- if (!ptk_structexists(ptk_stringtoint("structureid", sname)))
- {
- ptk_openstruct(ptk_stringtoint("structureid", sname));
- pcopy_all_elems_struct(sp->name);
- /* remove all execute structs */
- elptr = 0;
- elemlist[0] = PELEM_EXEC_STRUCT;
- pset_elem_ptr(0);
- do
- {
- ptk_findelemtype(elemlist, 1, PDIR_FORWARD, &srchstat, &elptr, &lstnum);
- if (srchstat == PSEARCH_STATUS_SUCCESS)
- {
- pset_elem_ptr(elptr);
- pdel_elem();
- }
- } while (srchstat == PSEARCH_STATUS_SUCCESS);
- ptk_closestruct();
- }
- if (validbox)
- {
- sh = ptk_point3(sp->pos.x, sp->pos.y, 0.0);
- ptk_shift3(&sh, PTYPE_REPLACE, topptr->mat);
- nodebox = ptk_limit3(-0.5, 0.5, -0.5, 0.5, 0.0, 1.0);
- ptk_box3tobox3(&boundbox, &nodebox, TRUE, PTYPE_PRECONCAT,
- topptr->mat, &err);
- pinq_elem_ptr(&err, &elptr);
- pset_elem_ptr(0);
- pset_elem_ptr_label(ptk_stringtoint("label", "globaltran"));
- pset_pick_id(sp->name);
- pset_local_tran3(topptr->mat, PTYPE_REPLACE);
- pexec_struct(ptk_stringtoint("structureid", sname));
- pset_elem_ptr(elptr + 3);
- note(sp->pos.x, sp->pos.y);
- }
- }
- else
- {
- sh = ptk_point3(sp->pos.x, sp->pos.y, 0.0);
- ptk_shift3(&sh, PTYPE_REPLACE, topptr->mat);
- nodebox = ptk_limit3(-0.5, 0.5, -0.5, 0.5, 0.0, 1.0);
- ptk_box3tobox3(&boundbox, &nodebox, TRUE, PTYPE_PRECONCAT, topptr->mat,
- &err);
- pinq_elem_ptr(&err, &elptr);
- pset_elem_ptr(0);
- pset_elem_ptr_label(ptk_stringtoint("label", "globaltran"));
- pset_pick_id(sp->name);
- pset_local_tran3(topptr->mat, PTYPE_REPLACE);
- pexec_struct(sp->name);
- pset_elem_ptr(elptr + 3);
- note(sp->pos.x, sp->pos.y);
- }
- }
- else
- drawnode(sp);
- } /* drawstructnode */
-
- /*--------------------------------------------------------------------------*/
-
- static void drawstructnetnodes(C(void))
- /*
- ** \blurb{Draw all nodes in structure network.}
- */
- {
- ptksstruct *s;
-
- s = topptr->structlist;
- while (s != NULL)
- {
- drawstructnetnode(s);
- s = s->next;
- }
- } /* drawstructnetnodes */
-
- /*--------------------------------------------------------------------------*/
-
- static void drawstructnodes(C(void))
- /*
- ** \blurb{Draw all nodes in structure network.}
- */
- {
- ptksstruct *s;
-
- s = topptr->structlist;
- while (s != NULL)
- {
- drawstructnode(s);
- s = s->next;
- }
- } /* drawstructnodes */
-
- /*--------------------------------------------------------------------------*/
-
- static void drawarc(C(Pint) n, C(ptksstruct *) pp, C(ptksstruct *) pc)
- PreANSI(Pint n)
- PreANSI(ptksstruct *pp)
- PreANSI(ptksstruct *pc)
- /*
- ** \parambegin
- ** \param{}{n}{number of reference to p}{IN}
- ** \param{}{pp}{pointer to parent record}{IN}
- ** \param{}{pc}{pointer to child record}{IN}
- ** \paramend
- ** \blurb{Draws the connecting arc to show a reference to 'child'
- ** by 'parent'. It is 'parent's nth reference.}
- */
- {
- Ppoint p[2];
- Ppoint_list pts;
-
- p[0] = ptk_point(pp->pos.x - topptr->nodewidth / 2 +
- n * topptr->nodewidth / (pp->numchildren + 1),
- pp->pos.y - topptr->nodeheight / 2);
- p[1] = ptk_point(pc->pos.x, pc->pos.y + topptr->nodeheight / 2);
- pts.num_points = 2;
- pts.points = p;
- ppolyline(&pts);
- } /* drawarc */
-
- /*--------------------------------------------------------------------------*/
-
- static void drawconnections(C(void))
- /*
- ** \blurb{This is called when all the structures' nodes have been
- ** placed, and draws the arcs between the nodes which represent structure
- ** references.}
- */
- {
- ptksstruct *s;
- ptksref *child;
- Pint childno;
-
- /* Wipe out the effects of any local trans for the nodes */
- ptk_unitmatrix3(topptr->mat);
- pset_local_tran3(topptr->mat, PTYPE_REPLACE);
- s = topptr->structlist;
- while (s != NULL)
- {
- /* process each structure in turn */
- child = s->firstchild;
- childno = 0;
- while (child != NULL)
- {
- /* process each child in order */
- childno++;
- drawarc(childno, s, child->structptr);
- child = child->next;
- }
- s = s->next;
- }
- } /* drawconnections */
-
- /*--------------------------------------------------------------------------*/
-
- static void addreference(C(ptksstruct *) pp, C(ptksstruct *) cp, C(Pint) e)
- PreANSI(ptksstruct *pp)
- PreANSI(ptksstruct *cp)
- PreANSI(Pint e)
- /*
- ** \parambegin
- ** \param{}{pp}{pointer to parent record}{IN}
- ** \param{}{cp}{pointer to child record}{IN}
- ** \param{}{e}{element pointer}{IN}
- ** \paramend
- ** \blurb{Stores a reference to 'child' at element e in 'parent'.}
- */
- {
- ptksref *newref;
-
- newref = (ptksref *)malloc(sizeof(ptksref));
- /* create a new reference node */
- if (pp->firstchild == NULL)
- pp->firstchild = newref;
- else
- pp->lastchild->next = newref;
- pp->lastchild = newref;
- newref->structptr = cp;
- newref->element = e;
- newref->next = NULL;
- } /* addreference */
-
- /*--------------------------------------------------------------------------*/
-
- static void storereferences(C(void))
- /*
- ** \blurb{Runs along the structlist, inquiring the children of
- ** each structure, and storing the reference information.}
- */
- {
- ptksstruct *s, *cp;
- Pint e, err, foundel, tempstruct, errnum, numelts;
- Psearch_status status;
- ptkselcontent elcont;
- Pint lstnum;
- Pstore store;
- Pelem_type exectype;
- Pelem_type_list includelst, excludelst;
-
- s = topptr->structlist;
- includelst.num_elem_types = 1;
- exectype = PELEM_EXEC_STRUCT;
- includelst.elem_types = &exectype;
- excludelst.num_elem_types = 0;
- excludelst.elem_types = NULL;
- while (s != NULL)
- {
- e = 0;
- numelts = ptk_elemcount(s->name);
- do
- {
- pelem_search(s->name, e, PDIR_FORWARD, &includelst, &excludelst, &err,
- &status, &foundel);
- e = foundel + 1;
- if (status == PSEARCH_STATUS_SUCCESS)
- {
- pcreate_store(&err, &store);
- ptk_inqelemtypesizecontent(s->name, foundel, store, &errnum,
- &elcont);
- tempstruct = elcont.eldata->int_data;
- ptk_delstore(store);
- lookupstructure(tempstruct, FALSE, &cp);
- addreference(s, cp, foundel);
- }
- } while ((status != PSEARCH_STATUS_FAILURE) && (e <= numelts));
- s = s->next; /* next structure */
- }
- } /* storereferences */
-
- /*--------------------------------------------------------------------------*/
-
- static ptksrow *selectrow(C(Pint) l, C(ptksrow **) last)
- PreANSI(Pint l)
- PreANSI(ptksrow **last)
- /*
- ** \blurb{Tries to return the address of the start of the `l'th row.
- ** If this row doesn't exist yet, rowptr is NIL, and a pointer
- ** to the previous row, if any, is returned in 'last'.}
- */
- {
- ptksrow *r;
- Pint lev;
-
- r = topptr->rowlist;
- lev = 1;
- *last = NULL;
- while (r != NULL && lev != l)
- {
- *last = r;
- r = r->next;
- lev++;
- }
- return r;
- } /* selectrow */
-
- /*--------------------------------------------------------------------------*/
-
- static void addtorowlist(C(ptksstruct *) sp, C(Pint) level)
- PreANSI(ptksstruct *sp)
- PreANSI(Pint level)
- /*
- ** \blurb{Adds an entry for `sp' to the `level'th row; also records
- ** the level in the structure entry.}
- */
- {
- ptksrow *last, *r, *newr;
- ptksnode *np, *newnp, *lastnp;
-
- r = selectrow(level, &last);
- if (r == NULL)
- {
- /* the required level doesn't yet exist */
- newr = (ptksrow *)malloc(sizeof(ptksrow));
- if (last == NULL)
- topptr->rowlist = newr;
- else
- last->next = newr;
- newr->next = NULL;
- newr->num = 0;
- newr->n = NULL;
- r = newr;
- }
-
- /* So now we are at the start of a row list, which may
- or may not be empty. Add the new node to the tail of it*/
- np = r->n;
- lastnp = NULL;
- r->num++;
- while (np != NULL)
- {
- lastnp = np;
- np = np->next;
- }
- /* now lastnp = tail */
- newnp = (ptksnode *)malloc(sizeof(ptksnode)); /*create the new node*/
- if (lastnp == NULL) /*chain to tail*/
- r->n = newnp; /*chain to row header*/
- else
- lastnp->next = newnp;
- newnp->structptr = sp;
- newnp->next = NULL;
- sp->level = level;
-
- /* keep track of the maximum level */
- if (level > topptr->maxlevel)
- topptr->maxlevel = level;
- } /* addtorowlist */
-
- /*--------------------------------------------------------------------------*/
-
- static ptksnode *selectrownode(C(ptksrow *) r, C(ptksstruct *) sp, C(ptksnode **)last)
- PreANSI(ptksrow *r)
- PreANSI(ptksstruct *sp)
- PreANSI(ptksnode **last)
- /*
- ** \blurb{Locates the given structure in the given row. It's address
- ** is returned as the result. Also, if there is a node immediately
- ** previous to this node, its address is returned in 'last',
- ** otherwise 'last' is NIL, which means that the first node in
- ** the row list was found.}
- */
- {
- ptksnode *np;
- ptkboolean found;
-
- np = r->n;
- found = FALSE;
- *last = NULL;
- while (np != NULL && !found)
- {
- if (np->structptr == sp)
- found = TRUE;
- else
- {
- *last = np; /* record the previous address */
- np = np->next;
- }
- }
- return np;
- } /* selectrownode */
-
- /*--------------------------------------------------------------------------*/
-
- static void deletefromrowlist(C(ptksstruct *) sp)
- PreANSI(ptksstruct *sp)
- /*
- ** \blurb{Deletes the entry for sp from its row.}
- */
- {
- ptksrow *r, *dummy;
- ptksnode *np, *last;
-
- r = selectrow(sp->level, &dummy);
- if (r == NULL)
- {
- /* printf("deletefromrowlist: row %d doesn't exist\n", sp->level); */
- return;
- }
- r->num--;
- np = selectrownode(r, sp, &last);
- if (np == NULL)
- {
- /* printf("deletefromrowlist: %d not found on row %d\n",
- sp->name, sp->level); */
- return;
- }
- if (last == NULL)
- r->n = np->next; /* first on the list */
- else
- last->next = np->next;
- free(np);
- } /* deletefromrowlist */
-
- /*--------------------------------------------------------------------------*/
-
- static void getpaths()
- {
- Pint totsize, err;
-
- pcreate_store(&err, &topptr->pathdata);
- pinq_paths_descs(topptr->root, PORDER_TOP_FIRST, 0, topptr->pathdata,
- &err, &topptr->pathlist);
- }
-
- /*--------------------------------------------------------------------------*/
-
- static void buildlists(C(void))
- /*
- ** \blurb{Constructs the main data structures used by the topology
- ** drawer. It creates the structure list, and the row list.}
- */
- {
- Pint cur_level, p, path;
- ptksstruct *sp;
- ptkboolean rowentryinvalid;
-
- /* do first node */
- lookupstructure(topptr->root, TRUE, &sp);
- addtorowlist(sp, 1);
- for (p = 0; p < topptr->pathlist->num_elem_ref_lists; p++)
- {
- /* do a path */
- cur_level = 1;
- for (path = 0; path < topptr->pathlist->elem_ref_lists[p].num_elem_refs;
- path++)
- {
- /* each member of path */
- rowentryinvalid = TRUE; /* assume it will change the row list */
- /* Look for this structure, and create it if it isn't there */
- if (!lookupstructure(topptr->pathlist->elem_ref_lists[p].elem_refs[path].struct_id, TRUE, &sp))
- {
- /* it was already there */
- if (sp->level < cur_level)
- deletefromrowlist(sp);
- else
- rowentryinvalid = FALSE;
- }
- if (rowentryinvalid)
- addtorowlist(sp, cur_level);
- cur_level++;
- } /* each member of path */
- /* go to next path */
- } /* a path */
- storereferences();
- ptk_delstore(topptr->pathdata);
- } /* buildlists */
-
- /*--------------------------------------------------------------------------*/
-
-
- static void disposenodelist(C(ptksnode *) nodeptr)
- PreANSI(ptksnode *nodeptr)
- {
- if (nodeptr->next == NULL)
- free(nodeptr);
- else
- disposenodelist(nodeptr->next);
- }
-
- /*--------------------------------------------------------------------------*/
-
- static void disposereflist(C(ptksref *) refptr)
- PreANSI(ptksref *refptr)
- {
- if (refptr->next == NULL)
- free(refptr);
- else
- disposereflist(refptr->next);
- }
-
- /*--------------------------------------------------------------------------*/
-
- static void disposestructlist(C(ptksstruct *) stptr)
- PreANSI(ptksstruct *stptr)
- {
- if (stptr->next == NULL)
- {
- if (stptr->firstchild != NULL)
- disposereflist(stptr->firstchild);
- if (stptr->firstparent != NULL)
- disposereflist(stptr->firstparent);
- free(stptr);
- }
- else
- disposestructlist(stptr->next);
- }
-
- /*--------------------------------------------------------------------------*/
-
- static void disposerowlist(C(ptksrow *) rowptr)
- PreANSI(ptksrow *rowptr)
- {
- if (rowptr->next == NULL)
- {
- if (rowptr->n != NULL)
- disposenodelist(rowptr->n);
- free(rowptr);
- }
- else
- disposerowlist(rowptr->next);
- }
-
- /*--------------------------------------------------------------------------*/
-
- static inqnamelist(C(ptksstruct *) stptr, C(Pint_list *) namelist)
- PreANSI(ptksstruct *stptr)
- PreANSI(Pint_list *namelist)
- {
- ptksref *refptr;
-
- refptr = stptr->firstchild;
- while (refptr != NULL)
- {
- if (inintlst(refptr->structptr->name, namelist) == -1)
- namelist->ints[namelist->num_ints++] = refptr->structptr->name;
- inqnamelist(refptr->structptr, namelist);
- refptr = refptr->next;
- }
- }
-
- /*--------------------------------------------------------------------------*/
-
- static void setnodeposition(C(Pint) topid, C(Pint) nodeid,
- C(Ppoint *) nodept, C(ptkenodetype) nodetype)
- PreANSI(Pint topid)
- PreANSI(Pint nodeid)
- PreANSI(Ppoint *nodept)
- PreANSI(ptkenodetype nodetype)
- {
- ptksstruct *structptr;
- Pint err, i, totsize;
- Ppoint3 toppt, nodept3;
- Pmatrix3 invglobalmat;
- Ppoint3 delta;
- Pint_list stids, nameset;
- Pint ids[255], name;
-
- settop(topid);
- ptk_invertmatrix3(topptr->globaltran, invglobalmat, &err);
- nodept3 = ptk_point3(nodept->x, nodept->y, 0.0);
- toppt = ptk_transform3(invglobalmat, &nodept3);
- switch (nodetype)
- {
- case PTKESINGLE:
- structptr = topptr->structlist;
- for (i = 0; i < nodeid; i++)
- structptr = structptr->next;
- structptr->pos = ptk_point(toppt.x, toppt.y);
- break;
-
- case PTKEGROUP:
- /* calculate dx, dy,
- follow ref list, add dx, dy to position
- */
- structptr = topptr->structlist;
- for (i = 0; i < nodeid; i++)
- structptr = structptr->next;
- delta = ptk_point3(toppt.x - structptr->pos.x,
- toppt.y - structptr->pos.y, 0.0);
- /* inquire structure identifiers of sub tree */
- stids.ints = ids;
- stids.num_ints = 1;
- ids[0] = structptr->name;
- inqnamelist(structptr, &stids);
- for (i = 0; i < stids.num_ints; i++)
- {
- structptr = topptr->structlist;
- while (structptr->name != stids.ints[i])
- structptr = structptr->next;
- structptr->pos.x += delta.x;
- structptr->pos.y += delta.y;
- }
- break;
- }
- /* remove keys */
- topptr->keyno = 0;
- for (i = 0; i <= 254; i++)
- topptr->rowmaxx[i] = -32768.0;
- ptk_openstruct(topptr->topologystid);
- pset_elem_ptr(0);
- pdel_elems_labels(ptk_stringtoint("label", "globaltran"),
- ptk_stringtoint("label", "highlightattrs"));
- pdel_elems_labels(ptk_stringtoint("label", "highlightnode"),
- ptk_stringtoint("label", "attrs"));
- pdel_elems_labels(ptk_stringtoint("label", "starttopology"),
- ptk_stringtoint("label", "endtopology"));
- topptr->extent = ptk_limit3(1000000.0, -10000000.0, 10000000.0,
- -10000000.0, 0.0, 1.0);
- pset_edit_mode(PEDIT_INSERT);
- setnode(1.0, 1.0);
- switch (topptr->topologytype)
- {
- case PTKEBOXTOPOLOGY:
- drawnodes();
- break;
-
- case PTKESTRUCTNETTOPOLOGY:
- drawstructnetnodes();
- break;
-
- case PTKESTRUCTTOPOLOGY:
- drawstructnodes();
- break;
- }
- nameset.ints = &name;
- nameset.num_ints = 1;
- name = topptr->topologyname;
- premove_names_set(&nameset);
- drawconnections();
- drawnames();
- drawkeys();
- setscaling();
- ptk_closestruct();
- } /* setnodeposition */
-
- /*--------------------------------------------------------------------------*/
-
- static void redrawtopology(C(void))
- {
- Pint_list nameset;
- Pint name, k;
-
- /* remove keys */
- topptr->keyno = 0;
- for (k = 0; k <= 254; k++)
- topptr->rowmaxx[k] = -32768.0;
- pempty_struct(topptr->topologystid);
- ptk_openstruct(topptr->topologystid);
-
- ptk_seteditmode(PEDIT_INSERT); /* We want to insert elements */
- nameset.ints = &name;
- nameset.num_ints = 1;
- name = topptr->topologyname;
- padd_names_set(&nameset);
- plabel(ptk_stringtoint("label", "globaltran"));
-
- plabel(ptk_stringtoint("label", "highlightattrs"));
- pset_edge_colr_ind(topptr->highlightedge);
- pset_int_colr_ind(topptr->highlightint);
- pset_int_style(PSTYLE_SOLID);
- pset_edge_flag(PEDGE_ON);
- plabel(ptk_stringtoint("label", "highlightnode"));
- plabel(ptk_stringtoint("label", "attrs"));
- pset_line_colr_ind(topptr->linecolour);
- pset_int_colr_ind(topptr->intcolour);
- pset_edge_colr_ind(topptr->edgecolour);
- pset_text_font(topptr->txfont);
- pset_text_colr_ind(topptr->textcolour);
- plabel(ptk_stringtoint("label", "starttopology"));
-
- placenodes();
- switch (topptr->topologytype)
- {
- case PTKEBOXTOPOLOGY:
- drawnodes();
- break;
-
- case PTKESTRUCTNETTOPOLOGY:
- drawstructnetnodes();
- break;
-
- case PTKESTRUCTTOPOLOGY:
- drawstructnodes();
- break;
- }
- premove_names_set(&nameset);
- drawconnections();
- drawnames();
-
- /* In case any nodes were labelled with keys because there was no room
- for proper annotation, draw the keytable. */
- drawkeys();
- plabel(ptk_stringtoint("label", "endtopology"));
-
- /* now we've drawn it all, so we find the appropriate scale to put it all
- in [0,1] */
- setscaling();
-
- ptk_unseteditmode();
- ptk_closestruct();
- } /* redrawtopology */
-
- /*--------------------------------------------------------------------------*/
- /*--------------------- External Topology Functions ------------------------*/
- /*--------------------------------------------------------------------------*/
-
- static void createtopology(C(Pint) topid, C(Pint) root, C(Pint) txfont,
- C(Pint) linecol, C(Pint) textcol, C(Pint) edgecol,
- C(Pint) intcol, C(Pint *) error)
- PreANSI(Pint topid)
- PreANSI(Pint root)
- PreANSI(Pint txfont)
- PreANSI(Pint linecol)
- PreANSI(Pint textcol)
- PreANSI(Pint edgecol)
- PreANSI(Pint intcol)
- PreANSI(Pint *error)
- /*
- ** \parambegin
- ** \param{Pint}{topid}{topology identifier}{IN}
- ** \param{Pint}{root}{structure network identifier}{IN}
- ** \param{Pint}{txfont}{label text font}{IN}
- ** \param{Pint}{linecol}{polyline colour index}{IN}
- ** \param{Pint}{textcol}{text colour index}{IN}
- ** \param{Pint}{edgecol}{edge colour index}{IN}
- ** \param{Pint}{intcol}{interior colour index}{IN}
- ** \param{Pint *}{error}{error code}{OUT}
- ** \paramend
- ** \blurb{Create topology diagram of given structure network.}
- */
- {
- Pint curname;
- char stname[255];
- Pint_list nameset;
- Pint name;
-
- /* if there already exists a topology with this identifier, error */
- *error = 0;
- settop(topid);
- if (topptr == NULL)
- {
- if (lasttop == NULL)
- {
- firsttop = lasttop = topptr =
- (ptkstopdraw *)malloc(sizeof(ptkstopdraw));
- topptr->next = NULL;
- }
- else
- {
- lasttop->next = topptr = (ptkstopdraw *)malloc(sizeof(ptkstopdraw));
- topptr->next = NULL;
- lasttop = lasttop->next;
- }
-
- topologycount++;
- topptr->topologyid = topid;
- topptr->posted.num_ints = 0;
- topptr->posted.ints = (Pint *)calloc(10, sizeof(Pint));
- sprintf(stname, "ptk$topology%d", topid);
- topptr->topologystid = ptk_stringtoint("structureid", stname);
- sprintf(stname, "name$topology%d", topid);
- topptr->topologyname = ptk_stringtoint("name", stname);
- topptr->root = root;
- topptr->topologytype = PTKEBOXTOPOLOGY;
- topptr->txfont = txfont;
- topptr->textcolour = textcol;
- topptr->linecolour = linecol;
- topptr->edgecolour = edgecol;
- topptr->intcolour = intcol;
- topptr->highlightnode = -1;
- topptr->highlightedge = intcol;
- topptr->highlightint = edgecol;
- *error = 0;
-
- if (!ptk_structexists(topptr->root))
- {
- *error = 1;
- fprintf(stderr, "ptk_createtopology: structure [%d] doesn't exist\n", topptr->root);
- return;
- }
-
- ptk_openstruct(topptr->topologystid);
-
- initialise();
- getpaths();
- buildlists();
-
- ptk_seteditmode(PEDIT_INSERT); /* We want to insert elements */
- nameset.ints = &name;
- nameset.num_ints = 1;
- name = topptr->topologyname;
- padd_names_set(&nameset);
- plabel(ptk_stringtoint("label", "globaltran"));
- plabel(ptk_stringtoint("label", "highlightattrs"));
- pset_edge_colr_ind(topptr->highlightedge);
- pset_int_colr_ind(topptr->highlightint);
- pset_int_style(PSTYLE_SOLID);
- pset_edge_flag(PEDGE_ON);
- plabel(ptk_stringtoint("label", "highlightnode"));
- plabel(ptk_stringtoint("label", "attrs"));
- pset_line_colr_ind(topptr->linecolour);
- pset_int_colr_ind(topptr->intcolour);
- pset_edge_colr_ind(topptr->edgecolour);
- pset_text_font(topptr->txfont);
- pset_text_colr_ind(topptr->textcolour);
- plabel(ptk_stringtoint("label", "starttopology"));
-
- placenodes();
- drawnodes();
- premove_names_set(&nameset);
- drawconnections();
- drawnames();
-
- /* In case any nodes were labelled with keys because there was no room
- for proper annotation, draw the keytable. */
- drawkeys();
- plabel(ptk_stringtoint("label", "endtopology"));
-
- /* now we've drawn it all, so we find the appropriate scale to put it all
- in [0,1] */
- setscaling();
-
- ptk_unseteditmode();
- ptk_closestruct();
- }
- else
- {
- *error = 2;
- }
- } /* createtopology */
-
- /*--------------------------------------------------------------------------*/
-
- /*function:external*/
- extern void ptk_createtopology(C(Pint) topid, C(Pint) root, C(Pint *) err)
- PreANSI(Pint topid)
- PreANSI(Pint root)
- PreANSI(Pint *err)
- /*
- ** \parambegin
- ** \param{Pint}{topid}{topology identifier}{IN}
- ** \param{Pint}{root}{structure network identifier}{IN}
- ** \param{Pint *}{error}{error code}{OUT}
- ** \paramend
- ** \blurb{This function creates a diagram of the structure network
- ** specified by {\tt root}. The diagram is a PHIGS structure which
- ** uses boxes connected by lines to represent structures and
- ** EXECUTE STRUCTURE elements. The error code = 1 if the root structure
- ** does not exist and = 2 if {\tt topid} already exists.
- ** This function requires hashtables "structureid", "label", "name".}
- */
- {
- createtopology(topid, root, 1, 1, 1, 1, 0, err);
- } /* ptk_createtopology */
-
- /*--------------------------------------------------------------------------*/
-
- /*function:external*/
- extern void ptk_settopologyattrs(C(Pint) topid, C(Pint) txfont,
- C(Pint) linecol, C(Pint) textcol, C(Pint) edgecol,
- C(Pint) intcol, C(Pint) htedgecol, C(Pint) htintcol)
- PreANSI(Pint topid)
- PreANSI(Pint txfont)
- PreANSI(Pint linecol)
- PreANSI(Pint textcol)
- PreANSI(Pint edgecol)
- PreANSI(Pint intcol)
- PreANSI(Pint htedgecol)
- PreANSI(Pint htintcol)
- /*
- ** \parambegin
- ** \param{Pint}{topid}{topology identifier}{IN}
- ** \param{Pint}{txfont}{label text font}{IN}
- ** \param{Pint}{linecol}{polyline colour index}{IN}
- ** \param{Pint}{textcol}{text colour index}{IN}
- ** \param{Pint}{edgecol}{edge colour index}{IN}
- ** \param{Pint}{intcol}{interior colour index}{IN}
- ** \param{Pint}{htedgecol}{highlight edge colour index}{IN}
- ** \param{Pint}{htintcol}{highlight interior colour index}{IN}
- ** \paramend
- ** \blurb{This function sets the text font and colour attribute values
- ** of a topology diagram. The text font applies to the structure
- ** names which are extracted from the \"structureid\" hashtable.
- ** The highlight colour indicies are used to highlight a single
- ** topology node in the function {\tt ptk\_settopologyhighlightnode}.}
- */
- {
- settop(topid);
- if (topptr != NULL)
- {
- topptr->txfont = txfont;
- topptr->textcolour = textcol;
- topptr->linecolour = linecol;
- topptr->edgecolour = edgecol;
- topptr->intcolour = intcol;
- topptr->highlightedge = htedgecol;
- topptr->highlightint = htintcol;
- redrawtopology();
- }
- } /* ptk_settopologyattrs */
-
- /*--------------------------------------------------------------------------*/
-
- /*function:external*/
- extern void ptk_inqtopologyattrs(C(Pint) topid, C(Pint *) txfont,
- C(Pint *) linecol, C(Pint *) textcol, C(Pint *) edgecol,
- C(Pint *) intcol, C(Pint *) htedgecol, C(Pint *) htintcol,
- C(Pint *) err)
- PreANSI(Pint topid)
- PreANSI(Pint *txfont)
- PreANSI(Pint *linecol)
- PreANSI(Pint *textcol)
- PreANSI(Pint *edgecol)
- PreANSI(Pint *intcol)
- PreANSI(Pint *htedgecol)
- PreANSI(Pint *htintcol)
- PreANSI(Pint *err)
- /*
- ** \parambegin
- ** \param{Pint}{topid}{topology identifier}{IN}
- ** \param{Pint *}{txfont}{label text font}{OUT}
- ** \param{Pint *}{linecol}{polyline colour index}{OUT}
- ** \param{Pint *}{textcol}{text colour index}{OUT}
- ** \param{Pint *}{edgecol}{edge colour index}{OUT}
- ** \param{Pint *}{intcol}{interior colour index}{OUT}
- ** \param{Pint *}{htedgecol}{highlight edge colour index}{OUT}
- ** \param{Pint *}{htintcol}{highlight interior colour index}{OUT}
- ** \param{Pint *}{err}{error indicator}{OUT}
- ** \paramend
- ** \blurb{This function may be used to obtain the text font and
- ** colour attribute values of a topology diagram. The error code = 1
- ** if {\tt topid} doesn't exist.}
- */
- {
- *err = 0;
- settop(topid);
- if (topptr != NULL)
- {
- *txfont = topptr->txfont;
- *textcol = topptr->textcolour;
- *linecol = topptr->linecolour;
- *edgecol = topptr->edgecolour;
- *intcol = topptr->intcolour;
- *htedgecol = topptr->highlightedge;
- *htintcol = topptr->highlightint;
- redrawtopology();
- }
- else
- *err = 1;
- } /* ptk_inqtopologyattrs */
-
- /*--------------------------------------------------------------------------*/
-
- /*function:external*/
- extern void ptk_createtopologypaths(C(Pint) topid,
- C(Pelem_ref_list_list *) paths, C(Pint *) error)
- PreANSI(Pint topid)
- PreANSI(Pelem_ref_list_list *paths)
- PreANSI(Pint *error)
- /*
- ** \parambegin
- ** \param{Pint}{topid}{topology identifier}{IN}
- ** \param{Pelem\_ref\_list\_list *}{paths}{structure-element paths}{IN}
- ** \param{Pint *}{error}{error code}{OUT}
- ** \paramend
- ** \blurb{This function creates a topology diagram using the structure
- ** path list {\tt paths}. This enables a topology diagram to be built
- ** of a non-existent structure network or of a subset of an actual
- ** structure network. The error code = 1 if {\tt topid} already exists.
- ** This function requires hashtables "structureid", "label", "name".}
- */
- {
- Pint curname;
- char stname[255];
- Pint_list nameset;
- Pint name;
-
- *error = 0;
- settop(topid);
- if (topptr == NULL)
- {
- if (lasttop == NULL)
- {
- firsttop = lasttop = topptr =
- (ptkstopdraw *)malloc(sizeof(ptkstopdraw));
- topptr->next = NULL;
- }
- else
- {
- lasttop->next = topptr = (ptkstopdraw *)malloc(sizeof(ptkstopdraw));
- topptr->next = NULL;
- lasttop = lasttop->next;
- }
-
- topologycount++;
- topptr->topologyid = topid;
- topptr->posted.num_ints = 0;
- topptr->posted.ints = (Pint *)calloc(10, sizeof(Pint));
- sprintf(stname, "ptk$topology%d", topid);
- topptr->topologystid = ptk_stringtoint("structureid", stname);
- sprintf(stname, "name$topology%d", topid);
- topptr->topologyname = ptk_stringtoint("name", stname);
- topptr->topologytype = PTKEBOXTOPOLOGY;
- topptr->txfont = 1;
- topptr->textcolour = 1;
- topptr->linecolour = 1;
- topptr->edgecolour = 1;
- topptr->intcolour = 0;
- topptr->highlightnode = -1;
- topptr->highlightedge = 0;
- topptr->highlightint = 1;
-
- if (paths->num_elem_ref_lists > 0)
- {
- topptr->root = paths->elem_ref_lists[0].elem_refs[0].struct_id;
-
- ptk_openstruct(topptr->topologystid);
- initialise();
- topptr->pathlist = paths;
- buildlists();
-
- ptk_seteditmode(PEDIT_INSERT); /* We want to insert elements */
- nameset.ints = &name;
- nameset.num_ints = 1;
- name = topptr->topologyname;
- padd_names_set(&nameset);
- plabel(ptk_stringtoint("label", "globaltran"));
-
- plabel(ptk_stringtoint("label", "highlightattrs"));
- pset_edge_colr_ind(topptr->highlightedge);
- pset_int_colr_ind(topptr->highlightint);
- pset_int_style(PSTYLE_SOLID);
- pset_edge_flag(PEDGE_ON);
- plabel(ptk_stringtoint("label", "highlightnode"));
- plabel(ptk_stringtoint("label", "attrs"));
- pset_line_colr_ind(topptr->linecolour);
- pset_int_colr_ind(topptr->intcolour);
- pset_edge_colr_ind(topptr->edgecolour);
- pset_text_font(topptr->txfont);
- pset_text_colr_ind(topptr->textcolour);
- plabel(ptk_stringtoint("label", "starttopology"));
-
- placenodes();
- drawnodes();
- premove_names_set(&nameset);
- drawconnections();
- drawnames();
-
- /* In case any nodes were labelled with keys because there was no room
- for proper annotation, draw the keytable. */
- drawkeys();
- plabel(ptk_stringtoint("label", "endtopology"));
-
- /* now we've drawn it all, so we find the appropriate scale to put it all
- in [0,1] */
- setscaling();
-
- ptk_unseteditmode();
- ptk_closestruct();
- }
- }
- else
- *error = 1;
- } /* ptk_createtopologypaths */
-
- /*--------------------------------------------------------------------------*/
-
- /*function:external*/
- extern void ptk_settopologytype(C(Pint) topid, C(ptketopologytype) toptype)
- PreANSI(Pint topid)
- PreANSI(ptketopologytype toptype)
- /*
- ** \parambegin
- ** \param{Pint}{topid}{topology identifier}{IN}
- ** \param{ptketopologytype}{toptype}{topology type}{IN}
- ** \paramend
- ** \blurb{This function sets the type of a topology diagram to
- ** BOX, STRUCT or STRUCTNET. The BOX topology type is the default and
- ** the STRUCT and STRUCTNET types insert parts of the actual structures
- ** into the nodes. As a result these topology types do not work well
- ** for networks containing SET VIEW INDEX and SET GLOBAL TRANSFORMATION
- ** elements.}
- */
- {
- settop(topid);
- if (topptr != NULL)
- {
- if (topptr->topologytype != toptype)
- {
- if (topptr->topologytype == PTKESTRUCTTOPOLOGY)
- delstructnodes();
- topptr->topologytype = toptype;
- redrawtopology();
- }
- }
- } /* ptk_settopologytype */
-
- /*--------------------------------------------------------------------------*/
-
- /*function:external*/
- extern void ptk_inqtopologytype(C(Pint) topid, C(ptketopologytype *) toptype,
- C(Pint *) err)
- PreANSI(Pint topid)
- PreANSI(ptketopologytype *toptype)
- PreANSI(Pint *err)
- /*
- ** \parambegin
- ** \param{Pint}{topid}{topology identifier}{IN}
- ** \param{ptketopologytype *}{toptype}{topology type}{OUT}
- ** \param{Pint *}{err}{error indicator}{OUT}
- ** \paramend
- ** \blurb{This function may be used to obtain the type of a topology
- ** diagram. The possible types are BOX, STRUCT and STRUCTNET, with BOX
- ** as the default. The error code = 1 if {\tt topid} doesn't exist.}
- */
- {
- *err = 0;
- settop(topid);
- if (topptr != NULL)
- {
- *toptype = topptr->topologytype;
- }
- else
- *err = 1;
- } /* ptk_inqtopologytype */
-
- /*--------------------------------------------------------------------------*/
-
- /*function:external*/
- extern void ptk_setnodeposition(C(Pint) topid, C(Pint) structid,
- C(Ppoint *) nodept, C(ptkenodetype) nodetype)
- PreANSI(Pint topid)
- PreANSI(Pint structid)
- PreANSI(Ppoint *nodept)
- PreANSI(ptkenodetype nodetype)
- /*
- ** \parambegin
- ** \param{Pint}{topid}{topology identifier}{IN}
- ** \param{Pint}{structid}{structure identifier}{IN}
- ** \param{Ppoint *}{nodept}{node position}{IN}
- ** \param{ptkenodetype}{nodetype}{type of node}{IN}
- ** \paramend
- ** \blurb{This function sets the position of a topology node or group
- ** of nodes. The position is given in the range [0, 1].
- ** The node is specified using the structure identifier of the structure
- ** that it represents. If nodetype is set to GROUP then all descendent
- ** nodes of {\tt structid} are moved relative to it.}
- */
- {
- ptksstruct *structptr;
- Pint nodeid;
- ptkboolean found;
-
- nodeid = 0;
- settop(topid);
- if (topptr != NULL)
- {
- structptr = topptr->structlist;
- found = FALSE;
- while ((!found) && (structptr != NULL))
- {
- if (structptr->name == structid)
- found = TRUE;
- else
- nodeid++;
- structptr = structptr->next;
- }
- if (found)
- setnodeposition(topid, nodeid, nodept, nodetype);
- }
- } /* ptk_setnodeposition */
-
- /*--------------------------------------------------------------------------*/
-
- /*function:external*/
- extern void ptk_inqnodeposition(C(Pint) topid, C(Pint) structid,
- C(Ppoint *) nodept, C(Pint *) err)
- PreANSI(Pint topid)
- PreANSI(Pint structid)
- PreANSI(Ppoint *nodept)
- PreANSI(Pint *err)
- /*
- ** \parambegin
- ** \param{Pint}{topid}{topology identifier}{IN}
- ** \param{Pint}{structid}{structure identifier}{IN}
- ** \param{Ppoint *}{nodept}{node position}{OUT}
- ** \param{Pint *}{err}{error indicator}{OUT}
- ** \paramend
- ** \blurb{This function may be used to obtain the position of a topology
- ** node in a topology diagram. The position is returned in the range [0, 1].
- ** The node is specified using the structure
- ** identifier of the structure that it represents. The error code = 1
- ** if {\tt topid} doesn't exist and = 2 if {\tt structid} is not a node
- ** in the topology.}
- */
- {
- ptksstruct *structptr;
- Pint nodeid;
- Ppoint3 nodept3;
- ptkboolean found;
-
- *err = 0;
- nodeid = 0;
- settop(topid);
- if (topptr != NULL)
- {
- structptr = topptr->structlist;
- found = FALSE;
- while ((!found) && (structptr != NULL))
- {
- if (structptr->name == structid)
- found = TRUE;
- else
- nodeid++;
- structptr = structptr->next;
- }
- if (found)
- {
- nodept3 = ptk_point3(structptr->pos.x, structptr->pos.y, 0.0);
- nodept3 = ptk_transform3(topptr->globaltran, &nodept3);
- *nodept = ptk_point(nodept3.x, nodept3.y);
- }
- else
- *err = 2;
- }
- else
- *err = 1;
- } /* ptk_inqnodeposition */
-
- /*--------------------------------------------------------------------------*/
-
- /*function:external*/
- extern void ptk_tidytopology(C(Pint) wsid, C(Pint) topid,
- C(ptkenodetype) nodetype,
- C(Pint) pickdev, C(Pint) pickpet, C(Ppick_data *) pickdatarec,
- C(Pint) locdev, C(Pint) locpet, C(Ploc_data *) locdatarec)
- PreANSI(Pint wsid)
- PreANSI(Pint topid)
- PreANSI(ptkenodetype nodetype)
- PreANSI(Pint pickdev)
- PreANSI(Pint pickpet)
- PreANSI(Ppick_data *pickdatarec)
- PreANSI(Pint locdev)
- PreANSI(Pint locpet)
- PreANSI(Ploc_data *locdatarec)
- /*
- ** \parambegin
- ** \param{Pint}{wsid}{workstation identifier}{IN}
- ** \param{Pint}{topid}{topology identifier}{IN}
- ** \param{ptkenodetype}{nodetype}{type of node}{IN}
- ** \param{Pint}{pickdev}{pick device}{IN}
- ** \param{Pint}{pickpet}{pick prompt/echo type}{IN}
- ** \param{Ppick\_data *}{pickdatarec}{pick data record}{IN}
- ** \param{Pint}{locdev}{locator device}{IN}
- ** \param{Pint}{locpet}{locator prompt/echo type}{IN}
- ** \param{Ploc\_data *}{locdatarec}{locator data record}{IN}
- ** \paramend
- ** \blurb{This function enables the user to set the position of
- ** a topology node, or group of nodes, interactively. The pick device
- ** {\tt pickdev} is used to request a topology node and if
- ** successful the locator device {\tt locdev} is used to specify
- ** a new node position. Prompt and echo types may be set for both
- ** the pick and locator devices.}
- */
- {
- Pint nodeid, inclnames, i, initview, viewindex;
- ptkboolean found;
- Ppick_path initpath, pick;
- Plimit3 echo;
- Ppick_path_elem pathel[10];
- Pfloat maxdevx, maxdevy, maxdevz;
- Pfilter pickfilt;
- Pin_status status;
- Ppoint initpos, locpos;
-
- settop(topid);
- if (topptr != NULL)
- {
- ptk_inqmaxdevicecoords3(wsid, &maxdevx, &maxdevy, &maxdevz);
- echo = ptk_limit3(0.0, maxdevx, 0.0, maxdevy, 0.0, maxdevz);
- /* pick topology node */
- pset_pick_mode(wsid, pickdev, POP_REQ, PSWITCH_ECHO);
- initpath.depth = 0;
- /* Implementation dependent code because of differences in
- ** valid initial status.
- */
- #ifdef SUN
- pinit_pick3(wsid, pickdev, PIN_STATUS_NONE, &initpath, pickpet, &echo,
- pickdatarec, PORDER_TOP_FIRST);
- #endif
- #ifdef HP
- pinit_pick3(wsid, pickdev, PIN_STATUS_NO_IN, &initpath, pickpet, &echo,
- pickdatarec, PORDER_TOP_FIRST);
- #endif
- pset_pick_mode(wsid, pickdev, POP_REQ, PSWITCH_ECHO);
- pickfilt.incl_set.num_ints = 1;
- pickfilt.incl_set.ints = &inclnames;
- inclnames = topptr->topologyname;
- pickfilt.excl_set.num_ints = 0;
- pset_pick_filter(wsid, pickdev, &pickfilt);
- pick.path_list = pathel;
- preq_pick(wsid, pickdev, 10, &status, &pick);
- if (status != PIN_STATUS_OK)
- return;
-
- /* find picked node */
- i = 0;
- found = FALSE;
- while ((!found) && (i < 10))
- {
- if (pick.path_list[i].struct_id == topptr->topologystid)
- {
- nodeid = pick.path_list[i].pick_id;
- found = TRUE;
- }
- i++;
- }
- /* locate point */
- pset_loc_mode(wsid, locdev, POP_REQ, PSWITCH_ECHO);
- initview = 0;
- initpos = ptk_point(0.5, 0.5);
- pinit_loc(wsid, locdev, initview, &initpos, locpet, &echo, locdatarec);
- pset_loc_mode(wsid, locdev, POP_REQ, PSWITCH_ECHO);
- preq_loc(wsid, locdev, &status, &viewindex, &locpos);
-
- if (status == PIN_STATUS_NONE)
- return;
-
- ptk_setnodeposition(topid, nodeid, &locpos, nodetype);
- }
- } /* ptk_tidytopology */
-
- /*--------------------------------------------------------------------------*/
-
- /*function:external*/
- extern void ptk_posttopology(C(Pint) wsid, C(Pint) topid, C(Pfloat) priority)
- PreANSI(Pint wsid)
- PreANSI(Pint topid)
- PreANSI(Pfloat priority)
- /*
- ** \parambegin
- ** \param{Pint}{wsid}{workstation identifier}{IN}
- ** \param{Pint}{topid}{topology identifier}{IN}
- ** \param{Pfloat}{priority}{display priority}{IN}
- ** \paramend
- ** \blurb{This function posts a topology diagram structure to the
- ** workstation {\tt wsid}.}
- */
- {
- settop(topid);
- if (topptr != NULL)
- {
- ptk_poststruct(wsid, topptr->topologystid, priority);
- addtointlst(wsid, &topptr->posted);
- }
- } /* ptk_posttopology */
-
- /*--------------------------------------------------------------------------*/
-
- /*function:external*/
- extern void ptk_unposttopology(C(Pint) wsid, C(Pint) topid)
- PreANSI(Pint wsid)
- PreANSI(Pint topid)
- /*
- ** \parambegin
- ** \param{Pint}{wsid}{workstation identifier}{IN}
- ** \param{Pint}{topid}{topology identifier}{IN}
- ** \paramend
- ** \blurb{This function unposts the topology diagram structure from
- ** the workstation {\tt wsid}.}
- */
- {
- settop(topid);
- if (topptr != NULL)
- {
- punpost_struct(wsid, topptr->topologystid);
- removefromintlst(wsid, &topptr->posted);
- }
- } /* ptk_unposttopology */
-
- /*--------------------------------------------------------------------------*/
-
- /*function:external*/
- extern ptkboolean ptk_deltopology(C(Pint) topid)
- PreANSI(Pint topid)
- /*
- ** \parambegin
- ** \param{Pint}{topid}{topology identifier}{IN}
- ** \paramend
- ** \blurb{This function deletes a topology diagram from the PHIGS Toolkit
- ** topology store. The function returns TRUE if a topology is deleted,
- ** otherwise FALSE.}
- */
- {
- ptkstopdraw *ptr, *junk;
- char stname[20];
-
- settop(topid);
- if (topptr != NULL)
- {
- if (topptr->topologytype == PTKESTRUCTTOPOLOGY)
- delstructnodes();
- ptr = firsttop;
- if (ptr->topologyid == topid)
- {
- firsttop = firsttop->next;
- if (lasttop->topologyid == topid)
- lasttop = firsttop;
- }
- else
- {
- while (ptr->next->topologyid != topid)
- {
- ptr = ptr->next;
- if (ptr->next == NULL)
- return FALSE;
- }
- junk = ptr->next;
- ptr->next = junk->next;
- if (ptr->next == NULL)
- lasttop = ptr;
- }
- pdel_struct(ptr->topologystid);
- /* dispose structlist */
- if (ptr->structlist != NULL)
- disposestructlist(ptr->structlist);
- /* dispose rowlist */
- if (ptr->rowlist != NULL)
- disposerowlist(ptr->rowlist);
- free(ptr);
-
- /* delete strings */
- sprintf(stname, "ptk$topology%d", topid);
- ptk_delstring("structureid", stname);
- sprintf(stname, "name$topology%d", topid);
- ptk_delstring("name", stname);
- topologycount--;
- return TRUE;
- }
- else
- return FALSE;
- } /* ptk_deltopology */
-
- /*--------------------------------------------------------------------------*/
-
- /*function:external*/
- extern void ptk_storetopologylayout(C(FILE *) fileptr, C(Pint) topid)
- PreANSI(FILE *fileptr)
- PreANSI(Pint topid)
- /*
- ** \parambegin
- ** \param{FILE *}{fileptr}{pointer to file}{OUT}
- ** \param{Pint}{topid}{topology identifier}{IN}
- ** \paramend
- ** \blurb{This function saves a topology layout in a text file. The
- ** layout refers to the positions of all the topology nodes. The
- ** format of the stored layout is:
- **
- ** {\tt start}
- ** {\tt (for each node in topology diagram)}
- ** {\tt x y}
- ** {\tt end}
- ** }
- */
- {
- ptksstruct *structptr;
-
- settop(topid);
- if (topptr != NULL)
- {
- structptr = topptr->structlist;
- fprintf(fileptr, "\nstart\n");
- while (structptr != NULL)
- {
- fprintf(fileptr, "%f %f\n", structptr->pos.x, structptr->pos.y);
- structptr = structptr->next;
- }
- fprintf(fileptr, "end\n");
- }
- } /* ptk_storetopologylayout */
-
- /*--------------------------------------------------------------------------*/
-
- /*function:external*/
- extern void ptk_restoretopologylayout(C(FILE *) fileptr, C(Pint) topid)
- PreANSI(FILE *fileptr)
- PreANSI(Pint topid)
- /*
- ** \parambegin
- ** \param{FILE *}{fileptr}{pointer to file}{OUT}
- ** \param{Pint}{topid}{topology identifier}{IN}
- ** \paramend
- ** \blurb{This function reads a topology layout from a text file.
- ** The layout is used to reposition the nodes of the topology
- ** diagram {\tt topid} but will only really make sense if the layout
- ** was stored originally from the same topology.}
- */
- {
- ptksstruct *structptr;
- char str[255];
- Pint_list nameset;
- Pint k;
-
- settop(topid);
- if (topptr != NULL)
- {
- structptr = topptr->structlist;
- /* find `start' */
- do
- {
- fgets(str, 255, fileptr);
- } while (strncmp(str, "start", 5) != 0);
- fgets(str, 255, fileptr);
- while ((structptr != NULL) && (strncmp(str, "end", 3) != 0))
- {
- sscanf(str, "%f %f\n", &structptr->pos.x, &structptr->pos.y);
- structptr = structptr->next;
- fgets(str, 255, fileptr);
- }
-
- /* remove keys */
- topptr->keyno = 0;
- for (k = 0; k <= 254; k++)
- topptr->rowmaxx[k] = -32768.0;
-
- ptk_openstruct(topptr->topologystid);
- pset_elem_ptr(0);
- pdel_elems_labels(ptk_stringtoint("label", "globaltran"),
- ptk_stringtoint("label", "highlightattrs"));
- pdel_elems_labels(ptk_stringtoint("label", "highlightnode"),
- ptk_stringtoint("label", "attrs"));
- pdel_elems_labels(ptk_stringtoint("label", "starttopology"),
- ptk_stringtoint("label", "endtopology"));
- topptr->extent = ptk_limit3(1000000.0, -10000000.0, 10000000.0,
- -10000000.0, 0.0, 1.0);
- pset_edit_mode(PEDIT_INSERT);
- setnode(1.0, 1.0);
- switch (topptr->topologytype)
- {
- case PTKEBOXTOPOLOGY:
- drawnodes();
- break;
-
- case PTKESTRUCTNETTOPOLOGY:
- drawstructnetnodes();
- break;
-
- case PTKESTRUCTTOPOLOGY:
- drawstructnodes();
- break;
- }
- nameset.num_ints = 1;
- nameset.ints = &topptr->topologyname;
- premove_names_set(&nameset);
- drawconnections();
- drawnames();
- drawkeys();
- setscaling();
- ptk_closestruct();
- }
- } /* ptk_restoretopologylayout */
-
- /*--------------------------------------------------------------------------*/
-
- /*function:external*/
- extern void ptk_inqpostedtopologies(C(Pint) wsid, C(Pint) size,
- C(Pint_list *) topids, C(Pint *) totalsize, C(Pint *) err)
- PreANSI(Pint wsid)
- PreANSI(Pint size)
- PreANSI(Pint_list *topids)
- PreANSI(Pint *totalsize)
- PreANSI(Pint *err)
- /*
- ** \parambegin
- ** \param{Pint}{wsid}{workstation identifier}{IN}
- ** \param{Pint}{size}{size of buffer}{IN}
- ** \param{Pint\_list *}{topids}{list of posted topologies}{OUT}
- ** \param{Pint *}{totalsize}{length of posted topologies list}{OUT}
- ** \param{Pint *}{err}{error indicator}{OUT}
- ** \paramend
- ** \blurb{This function may be used to obtain a list of all the
- ** topology diagrams which are posted to the workstation {\tt wsid}.}
- */
- {
- ptkstopdraw *ptrtop;
-
- *err = 0;
- *totalsize = 0;
- ptrtop = firsttop;
- while (ptrtop != NULL)
- {
- if ((inintlst(wsid, &ptrtop->posted) != -1))
- (*totalsize)++;
- ptrtop = ptrtop->next;
- }
- if (size >= *totalsize)
- {
- topids->num_ints = 0;
- ptrtop = firsttop;
- while (ptrtop != NULL)
- {
- if ((inintlst(wsid, &ptrtop->posted) != -1))
- {
- topids->ints[topids->num_ints] = ptrtop->topologyid;
- topids->num_ints++;
- }
- ptrtop = ptrtop->next;
- }
- }
- } /* ptk_inqpostedtopologies */
-
- /*--------------------------------------------------------------------------*/
-
- /*function:external*/
- extern void ptk_inqtopologyids(C(Pint) size, C(Pint_list *) topids,
- C(Pint *) totalsize, C(Pint *) err)
- PreANSI(Pint size)
- PreANSI(Pint_list *topids)
- PreANSI(Pint *totalsize)
- PreANSI(Pint *err)
- /*
- ** \parambegin
- ** \param{Pint}{size}{size of buffer}{IN}
- ** \param{Pint\_list *}{topids}{list of topology identifiers}{OUT}
- ** \param{Pint *}{totalsize}{length of topology identifiers list}{OUT}
- ** \param{Pint *}{err}{error indicator}{OUT}
- ** \paramend
- ** \blurb{This function may be used to obtain a list of all the topology
- ** diagrams in the PHIGS Toolkit topology store.}
- */
- {
- ptkstopdraw *ptrtop;
-
- *err = 0;
- *totalsize = topologycount;
- if (size >= *totalsize)
- {
- topids->num_ints = 0;
- ptrtop = firsttop;
- while (ptrtop != NULL)
- {
- topids->ints[topids->num_ints] = ptrtop->topologyid;
- topids->num_ints++;
- ptrtop = ptrtop->next;
- }
- }
- } /* ptk_inqtopologyids */
-
- /*--------------------------------------------------------------------------*/
-
- /*function:external*/
- extern void ptk_inqtopologystructid(C(Pint) topid, C(Pint *) topstid,
- C(Pint *) err)
- PreANSI(Pint topid)
- PreANSI(Pint *topstid)
- PreANSI(Pint *err)
- /*
- ** \parambegin
- ** \param{Pint}{topid}{topology identifier}{IN}
- ** \param{Pint *}{topstid}{topology structure identifier}{IN}
- ** \param{Pint *}{err}{error indicator}{OUT}
- ** \paramend
- ** \blurb{This function may be used to obtain the structure identifier
- ** of the topology diagram {\tt topid}. In the case of the BOX topology
- ** type the diagram is a single PHIGS structure but for STRUCT and
- ** STRUCTNET type diagrams it is a structure network.
- ** The error code = 1 if {\tt topid} doesn't exist.}
- */
- {
- *err = 0;
- settop(topid);
- if (topptr != NULL)
- *topstid = topptr->topologystid;
- else
- *err = 1;
- } /* ptk_inqtopologystructid */
-
- /*--------------------------------------------------------------------------*/
-
- /*function:external*/
- extern void ptk_inqtopologyname(C(Pint) topid, C(Pint *) name, C(Pint *) err)
- PreANSI(Pint topid)
- PreANSI(Pint *name)
- PreANSI(Pint *err)
- /*
- ** \parambegin
- ** \param{Pint}{topid}{topology identifier}{IN}
- ** \param{Pint *}{name}{topology name for nameset filters}{OUT}
- ** \param{Pint *}{err}{error indicator}{OUT}
- ** \paramend
- ** \blurb{This function may be used to obtain the topology name for use
- ** in the pick filter. When a topology name is added to the pick filter
- ** only the topology nodes are pickable.
- ** The error code = 1 if {\tt topid} doesn't exist.}
- */
- {
- *err = 0;
- settop(topid);
- if (topptr != NULL)
- {
- *name = topptr->topologyname;
- }
- else
- *err = 1;
- } /* ptk_inqtopologyname */
-
- /*--------------------------------------------------------------------------*/
-
- /*function:external*/
- extern void ptk_settopologyhighlightnode(C(Pint) topid, C(Pint) topnodestid)
- PreANSI(Pint topid)
- PreANSI(Pint topnodestid)
- /*
- ** \parambegin
- ** \param{Pint}{topid}{topology identifier}{IN}
- ** \param{Pint}{topnodestid}{topology node structure identifier}{IN}
- ** \paramend
- ** \blurb{This function highlights a single topology node by
- ** setting the colour attribute values of the edge and interior of
- ** the node box. This function only works for BOX topology types.}
- */
- {
- Pint nodeid;
- ptksstruct *structptr;
- ptkboolean found;
-
- found = FALSE;
- nodeid = 0;
- settop(topid);
- if (topptr != NULL)
- {
- structptr = topptr->structlist;
- while ((structptr != NULL) && (!found))
- {
- if (structptr->name == topnodestid)
- found = TRUE;
- else
- nodeid++;
- structptr = structptr->next;
- }
- if (found)
- {
- topptr->highlightnode = nodeid;
- redrawtopology();
- }
- }
- } /* ptk_settopologyhighlightnode */
-
- /*--------------------------------------------------------------------------*/
-
- /*function:external*/
- extern void ptk_inqtopologyhighlightnode(C(Pint) topid,
- C(Pint *) topnodestid, C(Pint *) err)
- PreANSI(Pint topid)
- PreANSI(Pint *topnodestid)
- PreANSI(Pint *err)
- /*
- ** \parambegin
- ** \param{Pint}{topid}{topology identifier}{IN}
- ** \param{Pint *}{topnodestid}{topology node structure identifier}{OUT}
- ** \param{Pint *}{err}{error indicator}{OUT}
- ** \paramend
- ** \blurb{This function may be used to obtain the structure
- ** identifier of the currently highlighted topology node. The error code
- ** = 1 if {\tt topid} doesn't exist and = 2 if there is no
- ** highlighted node.}
- */
- {
- Pint i;
- ptksstruct *structptr;
-
- *err = 0;
- settop(topid);
- if (topptr != NULL)
- {
- if (topptr->highlightnode != -1)
- {
- structptr = topptr->structlist;
- for (i = 0; i < topptr->highlightnode; i++)
- structptr = structptr->next;
- *topnodestid = structptr->name;
- }
- else
- *err = 2;
- }
- else
- *err = 1;
- } /* ptk_inqtopologyhighlightnode */
-
- /*--------------------------------------------------------------------------*/
-
- /* end of topo.c */
-
-